package com.cait.dutyfree.action.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.SessionAware;
import org.apache.struts2.util.ServletContextAware;

import com.cait.dutyfree.common.Activation;
import com.cait.dutyfree.common.Mail;
import com.cait.dutyfree.dataaccess.CusServiceDao;
import com.cait.dutyfree.exception.DutyFreeException;
import com.cait.dutyfree.pojo.Customer;
import com.cait.dutyfree.pojo.CustomerEvent;
import com.cait.dutyfree.pojo.CustomerLoginDetail;
import com.cait.dutyfree.security.Password;
import com.cait.dutyfree.security.Validator;
import com.opensymphony.xwork2.ActionSupport;

public class CusAction extends ActionSupport implements ServletContextAware,
		SessionAware, ServletRequestAware {

	private static final long serialVersionUID = -2747451109877964085L;
	private static final Logger logger = Logger.getLogger(LoginAction.class);
	private CusServiceDao userServiceDAO;

	private ServletContext servletContext;
	private HttpServletRequest request;
	private Map<String, Object> session;

	private String fName;
	private String username;
	private String password;
	private String email;
	private String lName;
	private String address;
	private String teleNo;
	private String mobileNo;
	private String cPassword;
	private String code;
	private String oldPassword;
	private int id;
	private int pageNo;
	private int noOfPages;

	private String u;
	private String uKey;

	private Customer user;

	List<Customer> users = new ArrayList<Customer>();
	List<CustomerLoginDetail> logs = new ArrayList<CustomerLoginDetail>();
	List<CustomerEvent> events = new ArrayList<CustomerEvent>();

	@Override
	public String execute() throws Exception {
		try {
			String result = getUserServiceDAO().userAuthentication(
					getUsername(), getPassword());

			if (result.equals("sucess")) {
				setUser(getUserServiceDAO().getUser(getUsername()));
				getSession().put("logedUser", getUser());
				getUserServiceDAO().updateUser(getUser());
				return SUCCESS;
			} else if (result.equals("block")) {
				addFieldError("block",
						"Your account has been blocked, Please contact administrator");
				logger.warn("");
				return NONE;
			} else if (result.equals("pending")) {
				addFieldError("pending", "Your account still not activated!!!");
				logger.warn("");
				return NONE;
			} else if (result.equals("deactivate")) {
				addFieldError("deactivate", "Your account is  deactivated!!!");
				logger.warn("");
				return NONE;
			} else {
				addFieldError("block", "User name or password incorrect");
				return NONE;
			}
		} catch (Exception e) {
			addFieldError("block", "Incorrect username or password");
			System.out.println(e);
			return NONE;
		}
	}

	public String logoff() {
		getSession().clear();
		return SUCCESS;
	}

	public String logoffByAdmin() {
		getSession().clear();
		return SUCCESS;
	}

	public String loadAddUserPage() {
		return SUCCESS;
	}

	public String admin() {

		System.out.println("***************" + getText("url"));
		System.out.println("***************" + getTexts());

		return SUCCESS;
	}

	public String saveUser() {

		Customer user = new Customer();
		boolean isValidForm = true;
		Password p = new Password("onlykalu");

		user.setFirstname(getfName());
		user.setUsername(getUsername());
		user.setPassword(p.encrypt(getPassword()));
		user.setEmail(getEmail());
		user.setLastname(getlName());
		user.setAddress(getAddress());
		user.setContactNo(getTeleNo());
		user.setMobileNo(getMobileNo());
		user.setCreatedDate(new Date());
		user.setStatus(-1);

		if (getfName().trim().length() < 2) {
			isValidForm = false;
			addFieldError("fName",
					"First name should be more than 2 charactors");
		}

		if (!Validator.isValidPassword(getUsername(), getPassword(),
				getcPassword())) {
			isValidForm = false;
			addFieldError("password", "Passwords must be more than 8 letters");
			addFieldError("password", "Passwords is not containing a number");
			addFieldError("password",
					"Password should not contain the username");
			addFieldError("password",
					"Passwords is not containing a special char");
			addFieldError("password", "Passwords and confirmation are not same");
		}

		if (!Validator.isValidEmailAddress(getEmail())) {
			isValidForm = false;
			addFieldError("email", "Invalid email address");
		}

		if (getTeleNo().trim().length() != 0) {
			if (Validator.isValidTelNo(getTeleNo())) {
				// isValidForm = false;
				// addFieldError("teleNo", "Invalid telephone number");
			}
		}

		if (getMobileNo().trim().length() != 0) {
			if (Validator.isValidTelNo(getMobileNo())) {
				// isValidForm = false;
				// addFieldError("teleNo", "Invalid mobile number");
			}
		}

		if (getCode().trim().length() != 4) {
			isValidForm = false;
			addFieldError("code", "Code should be with 4 charactors");
		}

		try {
			user.setPasswordResetCode(Integer.parseInt(getCode()));
		} catch (Exception e) {
			isValidForm = false;
			addFieldError("code", "Code should be numeric");
		}

		try {
			getText("url");
			if (getUserServiceDAO().isUserAvailable(getUsername().trim())) {
				isValidForm = false;
				addFieldError("username", "Username already available");
			}

			if (isValidForm) {
				getUserServiceDAO().addUser(user);
				Mail.sendAccountActivationMail(getEmail(), getfName(),
						Activation.generateLink(user.getId()));
				addActionMessage("User added successfully");
			}

		} catch (DutyFreeException e) {
			System.out.println(e.getErrorCode());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return NONE;
	}

	public String viewUsers() {

		try {
			setUsers(getUserServiceDAO().getUsers());
			return SUCCESS;
		} catch (Exception e) {
			addFieldError("block", "No user list available");
			return NONE;
		}

	}

	public String viewUser() {

		try {
			int id = Integer.parseInt(getRequest().getParameter("id"));
			setUser(getUserServiceDAO().getUser(id));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return SUCCESS;
	}

	public String userEvents() {

		try {
			setEvents(getUserServiceDAO().getAllEvents());
			setUsers(getUserServiceDAO().getUsers());
		} catch (Exception e) {
			return NONE;
		}
		return SUCCESS;

	}

	public String showUserEvents() {

		try {
			setUser(getUserServiceDAO().getUser(Integer.parseInt(getuKey())));
			if (getUser() != null)
				setEvents(getUserServiceDAO().getEvents(getUser()));
		} catch (Exception e) {
			// TODO: handle exception
			return NONE;
		}
		return SUCCESS;
	}

	public String loadUserLoginDetails() {

		int pageSize = 10, logSize;

		try {
			setId(Integer.parseInt(getRequest().getParameter("id")));
			setPageNo(1);
			if (getRequest().getParameter("pageNo") != null) {
				setPageNo(Integer.parseInt(getRequest().getParameter("pageNo")) + 1);
			}
			setUser(getUserServiceDAO().getUser(getId()));
			logSize = getUserServiceDAO().getDetails(getUser()).size();
			setNoOfPages(logSize / pageSize);
			if (logSize % pageSize == 0)
				setNoOfPages(getNoOfPages() - 1);
			setLogs(getUserServiceDAO().getDetails(getUser(), pageSize,
					getPageNo()));

		} catch (Exception e) {
			System.out.println(e);
		}
		return SUCCESS;
	}

	public String loadEditUserPage() {

		try {
			setId(Integer.parseInt(getRequest().getParameter("id")));
			setUser(getUserServiceDAO().getUser(getId()));
			getSession().put("userId", getId());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return SUCCESS;
	}

	public String editUser() {

		boolean isValidForm = true;

		try {
			int id = Integer.parseInt(getSession().get("userId").toString());
			setUser(getUserServiceDAO().getUser(id));
			getSession().remove("userId");

			getUser().setFirstname(getfName());
			getUser().setEmail(getEmail());
			getUser().setLastname(getlName());
			getUser().setAddress(getAddress());
			getUser().setContactNo(getTeleNo());
			getUser().setMobileNo(getMobileNo());
			getUser().setLastModifyDate(new Date());

			try {
				getUser().setPasswordResetCode(Integer.parseInt(getCode()));
			} catch (Exception e) {
				isValidForm = false;
				addFieldError("code", "Code should be numeric");
			}

			if (getfName().trim().length() < 2) {
				isValidForm = false;
				addFieldError("fName",
						"First name should be more than 2 charactors");
			}

			if (getCode().trim().length() != 4) {
				isValidForm = false;
				addFieldError("code", "Code should be with 4 charactors");
			}

			if (!Validator.isValidEmailAddress(getEmail())) {
				isValidForm = false;
				addFieldError("email", "Invalid email address");
			}

			if (getTeleNo().trim().length() != 0) {
				if (Validator.isValidTelNo(getTeleNo())) {
					// isValidForm = false;
					// addFieldError("teleNo", "Invalid telephone number");
				}
			}

			if (getMobileNo().trim().length() != 0) {
				if (Validator.isValidTelNo(getMobileNo())) {
					// isValidForm = false;
					// addFieldError("teleNo", "Invalid mobile number");
				}
			}

			if (isValidForm) {
				getUserServiceDAO().updateUser(getUser());
				addActionMessage("User updated successfully !!!");
				return SUCCESS;
			}
		} catch (Exception e) {
			System.out.println(e);
		}
		return NONE;

	}

	public String changePassword() {

		Password p = new Password("onlykalu");
		boolean isValidForm = true;

		try {
			Customer user = getUserServiceDAO()
					.getUser(
							Integer.parseInt(getSession().get("logedUserID")
									.toString()));

			if (!user.getPassword().equals(p.encrypt(getOldPassword()))) {
				isValidForm = false;
				addFieldError("oldPassword", "Old password is wrong!!!.");
			}

			if (getOldPassword().equals(getPassword())) {
				isValidForm = false;
				addFieldError("password",
						"Both old and new passwords are same.");
			}

			if (!(Validator.isValidPassword(user.getUsername(), getPassword(),
					getcPassword()))) {
				isValidForm = false;
				addFieldError("password",
						"Passwords must be more than 8 letters");
				addFieldError("password",
						"Passwords is not containing a number");
				addFieldError("password",
						"Password should not contain the username");
				addFieldError("password",
						"Passwords is not containing a special char");
				addFieldError("password",
						"Passwords and confirmation are not same");
			}

			if (isValidForm) {
				user.setPassword(p.encrypt(getPassword()));
				getUserServiceDAO().updateUser(user);
				addActionMessage("Password changed successfully");
				return SUCCESS;
			}
			return NONE;
		} catch (Exception e) {
			addFieldError("password", "Password not changed!!!");
			return NONE;
		}

	}

	public String showUserDetails() {
		try {
			setUser(getUserServiceDAO().getUser(getUsername()));
			return SUCCESS;
		} catch (Exception e) {
			return NONE;
		}
	}

	public String resetPassword() {

		Password p = new Password("onlykalu");

		try {
			Customer u = getUserServiceDAO().getUser(getUsername());

			if (u == null) {
				addFieldError("user", "Please select a user");
				return NONE;
			} else {
				String password = u.getId() + "@DFASS_"
						+ new SimpleDateFormat("yyyyMMdd").format(new Date());
				u.setPassword(p.encrypt(password));
				getUserServiceDAO().updateUser(u);
				addActionMessage("User reset successfully. New password is '"
						+ password + "'");
				return SUCCESS;
			}
		} catch (Exception e) {
			addFieldError("user", "User not reseted!!!");
			return NONE;
		}
	}

	public String activate() {

		try {
			String id = getRequest().getParameter("ui");
			String code = getRequest().getParameter("code");
			Password p = new Password("");

			if (id == null || code == null)
				return NONE; // invalid url

			Customer user = getUserServiceDAO().getUser(Integer.parseInt(id));
			if (user == null)
				return NONE;

			String str = (p.encrypt("" + user.getId()));

			if (str.equals(code)) { // valid url
				user.setStatus(0);
				getUserServiceDAO().updateUser(user);
				return SUCCESS;
			}

		} catch (Exception e) {
			System.out.println(e);
			return NONE;
		}
		return NONE;
	}

	public String deleteUser() {

		try {
			int id = Integer.parseInt(getRequest().getParameter("id"));
			setUser(getUserServiceDAO().getUser(id));
			getUser().setStatus(2);
			getUserServiceDAO().updateUser(getUser());
			viewUsers();
		} catch (Exception e) {
			// TODO: handle exception
		}
		return SUCCESS;
	}

	public String activateUser() {

		try {
			int id = Integer.parseInt(getRequest().getParameter("id"));
			setUser(getUserServiceDAO().getUser(id));
			getUser().setStatus(0);
			getUserServiceDAO().updateUser(getUser());
			viewUsers();
		} catch (Exception e) {
			// TODO: handle exception
		}
		return SUCCESS;
	}

	public void setServletContext(ServletContext context) {
		this.servletContext = context;
	}

	public ServletContext getServletContext() {
		return servletContext;
	}

	@SuppressWarnings("unchecked")
	public void setSession(@SuppressWarnings("rawtypes") Map session) {
		this.session = session;
	}

	public Map<String, Object> getSession() {
		return session;
	}

	public void setServletRequest(HttpServletRequest request) {
		this.request = request;
	}

	public HttpServletRequest getRequest() {
		return request;
	}

	/**
	 * @return the userServiceDAO
	 */

	/**
	 * @return the fName
	 */
	public String getfName() {
		return fName;
	}

	/**
	 * @param fName
	 *            the fName to set
	 */
	public void setfName(String fName) {
		this.fName = fName;
	}

	/**
	 * @return the username
	 */
	public String getUsername() {
		return username;
	}

	/**
	 * @param username
	 *            the username to set
	 */
	public void setUsername(String username) {
		this.username = username;
	}

	/**
	 * @return the password
	 */
	public String getPassword() {
		return password;
	}

	/**
	 * @param password
	 *            the password to set
	 */
	public void setPassword(String password) {
		this.password = password;
	}

	/**
	 * @return the email
	 */
	public String getEmail() {
		return email;
	}

	/**
	 * @param email
	 *            the email to set
	 */
	public void setEmail(String email) {
		this.email = email;
	}

	/**
	 * @return the lName
	 */
	public String getlName() {
		return lName;
	}

	/**
	 * @param lName
	 *            the lName to set
	 */
	public void setlName(String lName) {
		this.lName = lName;
	}

	/**
	 * @return the address
	 */
	public String getAddress() {
		return address;
	}

	/**
	 * @param address
	 *            the address to set
	 */
	public void setAddress(String address) {
		this.address = address;
	}

	/**
	 * @return the teleNo
	 */
	public String getTeleNo() {
		return teleNo;
	}

	/**
	 * @param teleNo
	 *            the teleNo to set
	 */
	public void setTeleNo(String teleNo) {
		this.teleNo = teleNo;
	}

	/**
	 * @return the mobileNo
	 */
	public String getMobileNo() {
		return mobileNo;
	}

	/**
	 * @param mobileNo
	 *            the mobileNo to set
	 */
	public void setMobileNo(String mobileNo) {
		this.mobileNo = mobileNo;
	}

	/**
	 * @return the cPassword
	 */
	public String getcPassword() {
		return cPassword;
	}

	/**
	 * @param cPassword
	 *            the cPassword to set
	 */
	public void setcPassword(String cPassword) {
		this.cPassword = cPassword;
	}

	/**
	 * @return the code
	 */
	public String getCode() {
		return code;
	}

	/**
	 * @param code
	 *            the code to set
	 */
	public void setCode(String code) {
		this.code = code;
	}

	/**
	 * @return the id
	 */
	public int getId() {
		return id;
	}

	/**
	 * @param id
	 *            the id to set
	 */
	public void setId(int id) {
		this.id = id;
	}

	/**
	 * @return the pageNo
	 */
	public int getPageNo() {
		return pageNo;
	}

	/**
	 * @param pageNo
	 *            the pageNo to set
	 */
	public void setPageNo(int pageNo) {
		this.pageNo = pageNo;
	}

	/**
	 * @return the noOfPages
	 */
	public int getNoOfPages() {
		return noOfPages;
	}

	/**
	 * @param noOfPages
	 *            the noOfPages to set
	 */
	public void setNoOfPages(int noOfPages) {
		this.noOfPages = noOfPages;
	}

	/**
	 * @return the u
	 */
	public String getU() {
		return u;
	}

	/**
	 * @param u
	 *            the u to set
	 */
	public void setU(String u) {
		this.u = u;
	}

	/**
	 * @return the uKey
	 */
	public String getuKey() {
		return uKey;
	}

	/**
	 * @param uKey
	 *            the uKey to set
	 */
	public void setuKey(String uKey) {
		this.uKey = uKey;
	}

	/**
	 * @return the user
	 */
	public Customer getUser() {
		return user;
	}

	/**
	 * @param user
	 *            the user to set
	 */
	public void setUser(Customer user) {
		this.user = user;
	}

	/**
	 * @return the oldPassword
	 */
	public String getOldPassword() {
		return oldPassword;
	}

	/**
	 * @param oldPassword
	 *            the oldPassword to set
	 */
	public void setOldPassword(String oldPassword) {
		this.oldPassword = oldPassword;
	}

	/**
	 * @return the users
	 */
	public List<Customer> getUsers() {
		return users;
	}

	/**
	 * @param users
	 *            the users to set
	 */
	public void setUsers(List<Customer> users) {
		this.users = users;
	}

	/**
	 * @return the logs
	 */
	public List<CustomerLoginDetail> getLogs() {
		return logs;
	}

	/**
	 * @param logs
	 *            the logs to set
	 */
	public void setLogs(List<CustomerLoginDetail> logs) {
		this.logs = logs;
	}

	/**
	 * @return the events
	 */
	public List<CustomerEvent> getEvents() {
		return events;
	}

	/**
	 * @param events
	 *            the events to set
	 */
	public void setEvents(List<CustomerEvent> events) {
		this.events = events;
	}

	public void setUserServiceDAO(CusServiceDao userServiceDAO) {
		this.userServiceDAO = userServiceDAO;
	}

	public CusServiceDao getUserServiceDAO() {
		return userServiceDAO;
	}

}